package main

import (
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"time"
)
type Msg struct {
	Errcode int `json:"errcode"`
	Errmsg string `json:"errmsg"`
	Access_token string `json:"access_token"`
	Expires_in int `json:"expires_in"`

}
type Msg1 struct{
	Errcode int `json:"errcode"`
	Errmsg string `json:"errmsg"`
	UserID string `json:"UserID"`
	DeviceID string`json:"DeviceID"`
}
type Address struct{
	Token string `json:"token"`
	Name string `json:"name"`
	TelNum string `json:"telNum"`
	A_sheng string`json:"a_sheng"`
	A_shi string`json:"a_shi"`
	Detail string`json:"detail"`
}
type Result struct {
	Token string `json:"token"`
	State int `json:"state"`
	Code string `json:"code"`
	Name string `json:"name"`
	TelNum string `json:"telNum"`
	A_sheng string`json:"a_sheng"`
	A_shi string`json:"a_shi"`
	Detail string`json:"detail"`
}
type Claims struct {
	UserID int
	jwt.StandardClaims
}
const SecretKey ="1"
var UserDb *sqlx.DB
func GetToken()(token string) {
	client := &http.Client{}//建立连接
	resp, err := client.Get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wx1d3765eb45497a18&corpsecret=QJg0azn19gs6HsQENJGlV3aSWEpvfi0bS4IWd6GSXJY")
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)//ReadAll 读取所有文件
	if err != nil {
		fmt.Println(err)}
	e := Msg{}
	if err := json.Unmarshal(body, &e); err != nil {
		panic(err)
	}//将json的数据转化为struct对象
	token = e.Access_token
	return token

}
func GetUserID(code string)(id string){

	client := &http.Client{}//建立连接
	var s = GetToken()
	 var URL =  "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token="+s+"&code="+code
	resp, err := client.Get(URL)
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)}
	e := Msg1{}
	if err := json.Unmarshal(body, &e); err != nil {
		panic(err)
	}
	id = e.UserID
	return id
}

func CreateToken(SecretKey []byte, issuer string, UserId int) (tokenString string, err error) {
	claims := &Claims{
		UserId,
		jwt.StandardClaims{
			ExpiresAt: int64(time.Now().Add(time.Hour * 72).Unix()),
			Issuer: issuer,
		},

	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err = token.SignedString(SecretKey)
	return
}
func ParseToken(tokenSrt string, SecretKey []byte) (claims jwt.Claims, err error) {
	var token *jwt.Token
	token, err = jwt.Parse(tokenSrt, func(*jwt.Token) (interface{}, error) {
		return SecretKey, nil
	})
	claims = token.Claims
	return
}



func putAddress (w http.ResponseWriter, r *http.Request){
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT,DELETE")
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
	w.Header().Set("content-type", "application/json;charset=UTF-8")
	    var errorcode int
        address :=Address{}
		switch r.Method {
		case http.MethodGet:
			body, err := ioutil.ReadAll(r.Body)
			if err != nil{
				errorcode = -1
				fmt.Fprintln(w, errorcode)
				return
			}
			if err := json.Unmarshal(body, &address); err != nil {
				panic(err)
			}

		}
		var token= GetUserID(address.Token)
	    claims, err := ParseToken(token, []byte(SecretKey))
			if nil != err {
				fmt.Fprintln(w, err)
			}
			 var userID =claims.(jwt.MapClaims)["UserID"]
	         fmt.Fprintln(w, userID)
		     var status = 1
	    _, err = UserDb.Exec("insert into addressTable (UserID, mobile,sheng,shi,detail,name) values(?,?,?,?)", userID,address.TelNum,address.A_sheng,address.A_shi,address.Detail,address.Name )
	    if err != nil {
			errorcode= -2
			fmt.Fprintln(w, errorcode)
		}else{
			_, err = UserDb.Exec("insert into userTable (is_address) values(?)", status)
			if(err != nil){
				errorcode = -3
				fmt.Fprintln(w, errorcode)
			}
			errorcode =0
			fmt.Fprintln(w, errorcode)
		}

}
func isaddress(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT,DELETE")
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
	w.Header().Set("content-type", "application/json;charset=UTF-8")
	if r.Method == "OPTIONS"{
		w.WriteHeader(http.StatusNoContent)
		return
	}
	var code string
	var result =Result{}
	switch r.Method {
	case http.MethodGet:
		values := r.URL.Query()
		code =values.Get("code")
	}
	var userID = GetUserID(code)
	result.State =-1

	var id int
	id,err:= strconv.Atoi(userID)
	if(err != nil){
		fmt.Fprintln(w,id)
	}else{
		token, _ := CreateToken([]byte(SecretKey), "OYZY", id)
		result.Token=token
	}

	err = UserDb.QueryRow("select is_address from userTable WHERE UserId=?", id).Scan(&result.State)
		if err != nil{
			fmt.Fprintln(w,"-2")
		} else {
			if result.State == 1 {
				rows := UserDb.QueryRow("select sheng,shi,detail,name,mobile from addressTable WHERE UserId=?", userID)
				err := rows.Scan(&result.A_sheng, &result.A_shi, &result.Detail, &result.Name, &result.TelNum)
				if err != nil {
					return
				}
				response, _ := json.Marshal(result)
				fmt.Fprintln(w, string(response))
			}
			if result.State == 0 {

				response, _ := json.Marshal(result)
				fmt.Fprintln(w, string(response))
			}
		}
		if result.State ==-1{
			response, _ := json.Marshal(result)
			fmt.Fprintln(w, string(response))
		}
	}



func init(){
	inituserdb()
}
func inituserdb(){
	db, err:=sqlx.Open("mysql","root:123456@tcp(userDB:3306)/userdb")
	if err != nil{
		log.Fatalln(err.Error())
	}
	UserDb = db
}

func main() {

	http.HandleFunc("/onload", isaddress)
	http.ListenAndServe(":3357", nil)
}
